#include "MediaUdpServer.h"
#include "MsgQueueManage.h"
#include <log.h>
#include<iostream>
#include<cstring>

using namespace std;

namespace Media{

std::map<uint16_t, MediaUdpServer *>      MediaUdpServer::sm_objectMap;
std::recursive_mutex 		              MediaUdpServer::sm_mapMutex;


MediaUdpServer *MediaUdpServer::instance(uint16_t port)
{
    std::lock_guard<std::recursive_mutex> guard(sm_mapMutex);
    
	if(sm_objectMap.find(port) == sm_objectMap.end())
	{
		sm_objectMap[port] = new MediaUdpServer(port);
	}

	return sm_objectMap[port];
}


MediaUdpServer::MediaUdpServer(uint16_t port) 
{   
    m_svrPort = port;
}

MediaUdpServer::~MediaUdpServer() 
{   
    if(m_svrSockfd > 0)
    {
        close(m_svrSockfd);
    }
}

bool MediaUdpServer::serverSocketInit()
{
    std::lock_guard<std::mutex> guard(m_connectMutex);
    
    if(m_connetStatus)
    {
        return true;
    }

    //创建客户端套接字 IPv4 tcp
	if((m_svrSockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
	{
		LOG_PrintError("socket error\n");
		return false;
	}
    
	
	memset(&m_svrSocketInfo, 0, sizeof(m_svrSocketInfo));
	
	m_svrSocketInfo.sin_family = AF_INET;//设置为IP通信
	m_svrSocketInfo.sin_addr.s_addr = INADDR_ANY;//服务器IP地址
	m_svrSocketInfo.sin_port = htons(m_svrPort); //服务器端口号
	
    if(bind(m_svrSockfd, (struct sockaddr *) &m_svrSocketInfo, sizeof(m_svrSocketInfo)) < 0)
    {
        LOG_PrintError("udpServer bind() errors\n");
        close(m_svrSockfd);
        return false;
    }

	LOG_PrintInfo("serverSocketInit success,m_svrPort:%d\n", m_svrPort);

	m_connetStatus = true;

	MsgQueueManage::instance(m_svrPort)->startReceiveTherad(); //启动单独线程处理接收的数据

	m_thread.start([this](Fdt::Thread *thread){this->ThreadProc(thread);}); //启动单独线程接收数据


	return true;
}

// 发送数据的方法  
bool MediaUdpServer::sendData(const char* data, size_t length)
{  
   if(m_svrSockfd < 0)
   {
        LOG_PrintError("socket fd error\n");
		return false;
   }
   
   int iRet = sendto(m_svrSockfd, data, length, 0, (const struct sockaddr*)&m_clientSocketInfo, sizeof(m_clientSocketInfo));  
   if (iRet == -1)
   {  
       LOG_PrintError("sendto failed\n");  
       return false;  
   }  
   
   return true;  
}


void MediaUdpServer::ThreadProc(Fdt::Thread *thread)
{
    thread->setPriority(Fdt::PRIORITY_NORMAL, Fdt::POLICY_RR);

    char recvBuf[RECEIVE_LEN];//数据接收缓冲区
    int len = 0;
    socklen_t clientSize = sizeof(m_clientSocketInfo);
    string  clientIp = {0};
    uint16_t clientPort = 0;
    
    while (thread->running())
    {
        if(!m_connetStatus)
        {
            thread->sleep(100);
            continue;
        } 

        //从客户端接受消息,暂时只处理一个客户端消息
        memset(recvBuf, 0, sizeof(recvBuf));
        
		len = recvfrom(m_svrSockfd, recvBuf, RECEIVE_LEN, 0, (struct sockaddr *)&m_clientSocketInfo, &clientSize);
        if(len > 0)
        {
		    recvBuf[len]='\0';		    

		    clientIp = inet_ntoa(m_clientSocketInfo.sin_addr);//网络字节序到字符串IP地址的转换
		    clientPort = ntohs(m_clientSocketInfo.sin_port);//网络字节序到主机字节序的转换
		    
		    printf("MediaUdpServer: clientIp=%s, clientPort=%d, recv_buf=%s, Info Length=%d\n", clientIp.c_str(), clientPort, recvBuf, len);

		    MsgQueueManage::MessagePtr msg(new MsgQueueManage::MessageBuffer(len + 1));
		    msg->commAddr = clientIp;
		    msg->commPort = clientPort;
            memcpy(msg->data, recvBuf, len + 1);
            msg->size = len;

		    MsgQueueManage::instance(m_svrPort)->SaveToCommQueue(msg);
        }

        thread->sleep(5);        
    }

    return;
}


}



